package com.kws.tool.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.kws.common.core.utils.StringUtils;
import com.kws.tool.dto.*;
import com.kws.tool.entity.CalculationFormOptionsEntity;
import com.kws.tool.entity.FeedInTariffEntity;
import com.kws.tool.service.CalculationFormOptionsService;
import com.kws.tool.service.CalculationService;
import com.kws.tool.service.FeedInTariffService;
import com.kws.tool.vo.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author : zhangbenting
 * @date : 2024/11/29 11:36
 * @Version: 1.0
 */
@Service
public class CalculationServiceImpl implements CalculationService {

    @Autowired
    private CalculationFormOptionsService calculationFormOptionsService;

    @Autowired
    private FeedInTariffService feedInTariffService;

    @Autowired
    private PhotovoltaicServiceImpl photovoltaicService;

    /**
     * 光伏测算
     *
     * @param photovoltaicDto
     * @return
     */
    @Override
    public PhotovoltaicVo photovoltaicCalculation(PhotovoltaicDto photovoltaicDto) {

        // 电站规模 (kW) = 屋顶面积 (m²) × 组件效率 (kW/m²)
        BigDecimal zjxl = BigDecimal.valueOf(Double.parseDouble(photovoltaicDto.getZjxl()))
                .divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
        BigDecimal dzgm = BigDecimal.valueOf(Double.parseDouble(photovoltaicDto.getWdmj()))
                .multiply(zjxl).setScale(2, RoundingMode.HALF_UP);

        // 总投资 = 电站规模 (kW) × 单位千瓦成本
        BigDecimal ztz = BigDecimal.valueOf(Double.parseDouble(photovoltaicDto.getMkwgfjscb()))
                .multiply(zjxl).setScale(2, RoundingMode.HALF_UP);

        // 年发电量 = 电站规模 × 满发小时数 × (1 - 首年衰减) × 发电效率
        BigDecimal fdxl = BigDecimal.valueOf(Double.parseDouble(photovoltaicDto.getFdxl()))
                .divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
        BigDecimal snsj = BigDecimal.valueOf(Double.parseDouble(photovoltaicDto.getSnsj()))
                .divide(BigDecimal.valueOf(100));
        BigDecimal zndj = BigDecimal.valueOf(Double.parseDouble(photovoltaicDto.getZndj()))
                .divide(BigDecimal.valueOf(100));
        BigDecimal nfdl = dzgm
                .multiply(BigDecimal.valueOf(Double.parseDouble(photovoltaicDto.getNlyxss())))
                .multiply(BigDecimal.ONE.subtract(snsj))
                .multiply(zndj)
                .setScale(2, RoundingMode.HALF_UP);

        // 总发电量
        BigDecimal zfdl = BigDecimal.ZERO;
        for (int t = 1; t <= Integer.parseInt(photovoltaicDto.getYynx()); t++) {
            BigDecimal annualPowerGenerationYearT = dzgm
                    .multiply(BigDecimal.valueOf(Double.parseDouble(photovoltaicDto.getNlyxss())))
                    .multiply(BigDecimal.ONE.subtract(BigDecimal.valueOf(Double.parseDouble(photovoltaicDto.getSnsj()))))
                    .multiply(BigDecimal.valueOf(Math.pow(1 - Double.parseDouble(photovoltaicDto.getZndj()), t - 1)))
                    .multiply(fdxl).setScale(2, RoundingMode.HALF_UP);
            zfdl = zfdl.add(annualPowerGenerationYearT);
        }
        // 年收益
        BigDecimal nsy = calculateAnnualRevenueBigDecimal(photovoltaicDto, nfdl);

        // 总收益
        BigDecimal zsy = BigDecimal.ZERO;
        for (int t = 1; t <= Double.parseDouble(photovoltaicDto.getYynx()); t++) {
            BigDecimal annualRevenueYearT = calculateAnnualRevenueBigDecimal(photovoltaicDto,
                    nfdl.multiply(BigDecimal.valueOf(Math.pow(1 - Double.parseDouble(photovoltaicDto.getSnsj()), t - 1)))
                            .setScale(2, RoundingMode.HALF_UP));
            zsy = zsy.add(annualRevenueYearT);
        }

        // 回报周期 = 总投资 / 年收益
        BigDecimal hbzq = ztz
                .divide(nsy, 2, RoundingMode.HALF_UP);

        // 投资收益率 = (总收益 - 总投资) / 总投资 × 100
        BigDecimal tzsyl = zsy
                .subtract(ztz)
                .divide(ztz, 4, RoundingMode.HALF_UP)
                .multiply(BigDecimal.valueOf(100))
                .setScale(2, RoundingMode.HALF_UP);

        //每KW光伏运维成本 = 运维总成本/报装容量
        BigDecimal mkwgfywcb = BigDecimal.valueOf(Double.parseDouble(photovoltaicDto.getMkwgfywcb()));

        // 年运维成本 = 电站规模 × 单位千瓦运维成本
        BigDecimal nywcb = dzgm.multiply(mkwgfywcb).setScale(2, RoundingMode.HALF_UP);

        // 每KW光伏建设成本 = 总投资/报装容量
        BigDecimal njscb = ztz.divide(dzgm, 2, RoundingMode.HALF_UP);

        // 总减碳量 = 总发电量 × 减碳系数
        BigDecimal zjtl = zfdl
                .multiply(BigDecimal.valueOf(Double.parseDouble(photovoltaicDto.getJtxs())))
                .setScale(2, RoundingMode.HALF_UP);

        // 创建输出对象并设置计算结果
        PhotovoltaicVo photovoltaicVo = new PhotovoltaicVo();
        photovoltaicVo.setZtz(ztz.toString());
        photovoltaicVo.setDzgm(dzgm.toString());
        photovoltaicVo.setNfdl(nfdl.toString());
        photovoltaicVo.setZfdl(zfdl.toString());
        photovoltaicVo.setNsy(nsy.toString());
        photovoltaicVo.setZsy(zsy.toString());
        photovoltaicVo.setNywcb(nywcb.toString());
        BigDecimal mkwjscb = BigDecimal.valueOf(Double.parseDouble(photovoltaicDto.getMkwgfjscb()));
        photovoltaicVo.setMkwgfjscb(mkwjscb.toString());
        photovoltaicVo.setHbzq(hbzq.toString());
        photovoltaicVo.setTzsyl(tzsyl.toString());
        photovoltaicVo.setZjtl(zjtl.toString());
        return photovoltaicVo;

    }

    /**
     * 计算年收益。
     *
     * @param photovoltaicDto       输入数据
     * @param annualPowerGeneration 年发电量
     * @return 年收益
     */
//    private double calculateAnnualRevenue(PhotovoltaicDto photovoltaicDto, double annualPowerGeneration) {
//        // 根据用电方式不同，年收益可分为三种情况
//        if ("自发自用".equals(photovoltaicDto.getPowerUsageType())) {
//            return annualPowerGeneration * photovoltaicDto.getPremiumElectricityPrice();
//        } else if ("全额上网".equals(photovoltaicDto.getPowerUsageType())) {
//            return annualPowerGeneration * photovoltaicDto.getOnGridElectricityPrice();
//        } else if ("余电上网".equals(photovoltaicDto.getPowerUsageType())) {
//            return annualPowerGeneration * photovoltaicDto.getPremiumElectricityPrice() + (annualPowerGeneration - annualPowerGeneration * photovoltaicDto.getSplitRatio()) * photovoltaicDto.getOnGridElectricityPrice();
//        }
//        return 0;
//    }
    private BigDecimal calculateAnnualRevenueBigDecimal(PhotovoltaicDto photovoltaicDto, BigDecimal annualPowerGeneration) {
        if ("自发自用".equals(photovoltaicDto.getYdfs())) {
            return BigDecimal.valueOf(Double.parseDouble(photovoltaicDto.getZydlOrnydl()))
                    .multiply(BigDecimal.valueOf(Double.parseDouble(photovoltaicDto.getJqdj())))
                    .setScale(2, RoundingMode.HALF_UP);
        } else if ("全额上网".equals(photovoltaicDto.getYdfs())) {
            return annualPowerGeneration
                    .multiply(BigDecimal.valueOf(Double.parseDouble(photovoltaicDto.getSwdl())))
                    .setScale(2, RoundingMode.HALF_UP);
        } else if ("余电上网".equals(photovoltaicDto.getYdfs())) {
            return BigDecimal.valueOf(Double.parseDouble(photovoltaicDto.getZydlOrnydl()))
                    .multiply(BigDecimal.valueOf(Double.parseDouble(photovoltaicDto.getJqdj())))
                    .add(BigDecimal.valueOf(Double.parseDouble(photovoltaicDto.getSwdl())))
                    .multiply(BigDecimal.valueOf(Double.parseDouble(photovoltaicDto.getSwdl())))
                    .setScale(2, RoundingMode.HALF_UP);
        }
        return BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
    }

    /**
     * 储能测算
     *
     * @param energyStorageDto 输入数据
     * @return 输出数据
     */
    @Override
    public EnergyStorageVo energyStorageCalculation(EnergyStorageDto energyStorageDto) {

        // 计算储能系统功率
        BigDecimal cnxtgl = BigDecimal.valueOf(Double.parseDouble(energyStorageDto.getDxrfqx()))
                .setScale(2, RoundingMode.HALF_UP);

        // 计算储能电池总容量, 储能电池总容量 (kWh)=储能系统功率 (kW)×放电时长 (h)÷放电深度
        BigDecimal fdsd = BigDecimal.valueOf(Double.parseDouble(energyStorageDto.getFdsd()))
                .divide(BigDecimal.valueOf(100));
        BigDecimal cddczrl = cnxtgl.multiply(BigDecimal.valueOf(
                        Double.parseDouble(energyStorageDto.getFdsc())))
                .divide(fdsd, 2, RoundingMode.HALF_UP);

        // 计算建设成本,储能电池总容量 (kWh)×单位造价 (元/kWh)
        BigDecimal jscb = cddczrl.multiply(BigDecimal.valueOf
                        (Double.parseDouble(energyStorageDto.getDwzj())))
                .setScale(2, RoundingMode.HALF_UP);

        // 计算年运维成本,储能电池总容量 (kWh)×每kWh运维成本 (元/kWh)
        BigDecimal nywcb = cddczrl.multiply(BigDecimal.valueOf(Double.parseDouble(energyStorageDto.getMkwhywcb())))
                .setScale(2, RoundingMode.HALF_UP);

        //循环时间
        BigDecimal xhsj = BigDecimal.valueOf(Double.parseDouble(energyStorageDto.getMcxhsj()));
        //年循环次数 = 运营时间/年 ÷ 每次循环时间。
        BigDecimal nxhcs = BigDecimal.valueOf(Double.parseDouble(energyStorageDto.getYysj()))
                .multiply(xhsj).setScale(2, RoundingMode.HALF_UP);
        //充放电量,充放电量 (kWh)=储能电池总容量 (kWh)×年循环次数
        BigDecimal cfdl = jscb.multiply(nxhcs).setScale(2, RoundingMode.HALF_UP);
        // 峰电价与谷电价的差价
        BigDecimal fgcj = BigDecimal.valueOf(Double.parseDouble(energyStorageDto.getFsdj()))
                .subtract(BigDecimal.valueOf(Double.parseDouble(energyStorageDto.getGsdj())));
        //总收益 (元)=充放电量 (kWh)×(峰电价 (元/kWh)−谷电价 (元/kWh))
        BigDecimal zsy = cfdl.multiply(fgcj).setScale(2, RoundingMode.HALF_UP);

        //年收益
        BigDecimal nsy = zsy.divide(BigDecimal.valueOf(Double.parseDouble(energyStorageDto.getYysj())), 2, RoundingMode.HALF_UP);

        // 计算回报周期  回报周期 (年)=年收益/建设成本
        BigDecimal hbzq = zsy.divide(jscb, 2, RoundingMode.HALF_UP);

        // 计算投资收益率 投资收益率=(总收益−建设成本)/建设成本×100%
        BigDecimal tzsyl = zsy.subtract(jscb).divide(jscb, 2, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)).setScale(2, RoundingMode.HALF_UP);

        //更换成本 (元)=储能电池总容量 (kWh)×单位造价 (元/kWh)×更换次数
        //更换次数为零时，更换成本为0
        BigDecimal ghcs = BigDecimal.valueOf(Double.parseDouble(energyStorageDto.getGhcs()))
                .multiply(cddczrl).multiply(BigDecimal.valueOf(Double.parseDouble(energyStorageDto.getDwzj())))
                .setScale(2, RoundingMode.HALF_UP);

        // 计算经济评价,经济评价 (元)=总收益−(建设成本+年运维成本×使用年限+更换成本)
        BigDecimal jjpj = zsy.subtract(jscb.add(nywcb.
                        multiply(BigDecimal.valueOf(Double.parseDouble(energyStorageDto.getSynx())))))
                .add(ghcs).setScale(2, RoundingMode.HALF_UP);

        //充放策略
        String cfcl = "1、在谷电价时段充电 2、在峰电价时段放电";

        // 设置输出数据
        EnergyStorageVo energyStorageVo = new EnergyStorageVo();
        energyStorageVo.setCnxtgl(cnxtgl.toString());
        energyStorageVo.setCndczrl(cddczrl.toString());
        energyStorageVo.setJscb(jscb.toString());
        energyStorageVo.setNywcb(nywcb.toString());
        energyStorageVo.setZsy(zsy.toString());
        energyStorageVo.setCfdl(cfdl.toString());
        energyStorageVo.setNxhcs(nxhcs.toString());
        energyStorageVo.setHbzq(hbzq.toString());
        energyStorageVo.setTzsyl(tzsyl.toString());
        energyStorageVo.setJjpj(jjpj.toString());
        energyStorageVo.setCfcl(cfcl);
        energyStorageVo.setGhcb(ghcs.toString());
//        energyStorageVo.setFgdcj(fgcj.toString());
//        energyStorageVo.setCnnsy(nsy.toString());
        return energyStorageVo;
    }


    /**
     * 充电桩测算
     *
     * @param electricPileDto
     * @return
     */
    @Override
    public ElectricPileVo electricPileCalculation(ElectricPileDto electricPileDto) {
        ElectricPileVo electricPileVo = new ElectricPileVo();

        // 总投资 (元)=充电桩总成本+配电设备总成本+土建施工总成本+变压器成本
        // 计算充电桩总成本
        BigDecimal cdzzcb = BigDecimal.valueOf(Double.parseDouble(electricPileDto.getCdzsl()))
                .multiply(BigDecimal.valueOf(Double.parseDouble(electricPileDto.getCdzdj())))
                .setScale(2, RoundingMode.HALF_UP);
        // 计算配电设备总成本 配电设备总成本 (元)=变压器容量 (KVA)×配电设备单价 (元/KVA)
        BigDecimal pdsbzcb = BigDecimal.ZERO;
        if (!StringUtils.isEmpty(electricPileDto.getByqrl())) {
            pdsbzcb = BigDecimal.valueOf(Double.parseDouble(electricPileDto.getByqrl()))
                    .multiply(BigDecimal.valueOf(Double.parseDouble(electricPileDto.getPdsbdj())))
                    .setScale(2, RoundingMode.HALF_UP);
        }
        // 计算土建施工总成本 土建施工总成本 (元)=土建施工面积 (平方米)×土建施工单价 (元/平方米
        BigDecimal tjsgzcb = BigDecimal.valueOf(Double.parseDouble(electricPileDto.getAzmj()))
                .multiply(BigDecimal.valueOf(Double.parseDouble(electricPileDto.getTjsgdj())))
                .setScale(2, RoundingMode.HALF_UP);
        // 计算总投资
        BigDecimal ztz = cdzzcb.add(pdsbzcb).add(tjsgzcb);
        electricPileVo.setZtz(ztz.toString());
        electricPileVo.setCdzzcb(cdzzcb.toString());
        electricPileVo.setPdsbzcb(pdsbzcb.toString());
        electricPileVo.setTjsgzcb(tjsgzcb.toString());
        //年充电量
        BigDecimal syl = BigDecimal.valueOf(Double.parseDouble(electricPileDto.getSyl())).divide(BigDecimal.valueOf(100));
        BigDecimal ncdl = BigDecimal.valueOf(Double.parseDouble(electricPileDto.getCdzsl()))
                .multiply(BigDecimal.valueOf(Double.parseDouble(electricPileDto.getDzgl())))
                .multiply(syl).multiply(BigDecimal.valueOf(Double.parseDouble(electricPileDto.getYyxss())));
        electricPileVo.setNcdl(ncdl.toString());
        //年运营收入
        BigDecimal nyysr = ncdl.multiply(BigDecimal.valueOf(Double.parseDouble(electricPileDto.getFwf())))
                .setScale(2, RoundingMode.HALF_UP);
        electricPileVo.setNyysr(nyysr.toString());

        //折旧成本 (元)=总投资 (元)/使用年限 (年)
        BigDecimal zjcb = ztz.divide(BigDecimal.valueOf(Double.parseDouble
                (electricPileDto.getSynx())), 2, RoundingMode.HALF_UP);
        electricPileVo.setZjcb(zjcb.toString());
        //年运维成本 (元)=充电桩数量×年运营单价 (元/台)
        BigDecimal nywcb = BigDecimal.valueOf(Double.parseDouble(electricPileDto.getCdzsl()))
                .multiply(BigDecimal.valueOf(Double.parseDouble(electricPileDto.getNyydj())))
                .setScale(2, RoundingMode.HALF_UP);
        electricPileVo.setNywcb(nywcb.toString());
        //年运营成本 (元)=折旧成本+年运维成本
        //计算年运营成本
        BigDecimal nyycb = zjcb.add(nywcb);
        electricPileVo.setNyycb(nyycb.toString());

        //计算回报周期
        BigDecimal hbzq = ztz.divide((nyysr.subtract(nyycb)), 2, RoundingMode.HALF_UP);
        electricPileVo.setHbzq(hbzq.toString());

        // 计算投资收益率
        BigDecimal tzsyl = (nyysr.subtract(nyycb)).divide(ztz, 2, RoundingMode.HALF_UP)
                .multiply(BigDecimal.valueOf(100));
        electricPileVo.setTzsyl(tzsyl.toString());

        return electricPileVo;
    }

//    /**
//     * 计算年运营收入
//     *
//     * @param input
//     * @return
//     */
//    private BigDecimal calculateAnnualOperatingIncome(ElectricPileDto input) {
//        //单桩功率
//        double singlePilePower = 0;
//        String chargingPileType = input.getCdzlx();
//        if ("快充".equals(chargingPileType)) {
//            singlePilePower = 60;
//        } else if ("慢充".equals(chargingPileType)) {
//            singlePilePower = 7;
//        } else if ("超充".equals(chargingPileType)) {
//            singlePilePower = 120;
//        }
//        //计算年充电量,年充电量 (kWh)=单桩功率 (kW)×使用率×运营小时数 (小时/年)×充电桩数量
//        BigDecimal ncdl = BigDecimal.valueOf(Double.parseDouble(input.getCdzsl()))
//                .multiply(BigDecimal.valueOf(singlePilePower))
//                .multiply(BigDecimal.valueOf(Double.parseDouble(input.getSyl())))
//                .multiply(BigDecimal.valueOf(Double.parseDouble(input.getYyxss())));
//        //年运营收入 年充电量 (kWh)×服务费 (元/kWh)
//        return ncdl.multiply(BigDecimal.valueOf(Double.parseDouble(input.getFwf())));
//    }

    @Override
    public WindPowerVo windPowerCalculation(WindPowerDto windPowerDto) {

        // 电站规模 (kW)=风机数量×单台风机功率 (kW)
        BigDecimal dzgm = BigDecimal.valueOf(Double.parseDouble(windPowerDto.getFjsl()))
                .multiply(BigDecimal.valueOf(Double.parseDouble(windPowerDto.getDtfjgl())))
                .setScale(2, RoundingMode.HALF_UP);

        // 总投资 (元)=电站规模 (kW)×每KW建设成本 (元/kW)
        BigDecimal ztz = dzgm.multiply(BigDecimal.valueOf(Double.parseDouble(windPowerDto.getMkwjscb())))
                .setScale(2, RoundingMode.HALF_UP);

        //年发电量 (kWh)=电站规模 (kW)×年利用小时数 (小时/年)
        BigDecimal nfdl = dzgm.multiply(BigDecimal.valueOf(Double.parseDouble(windPowerDto.getNlyxss())))
                .setScale(2, RoundingMode.HALF_UP);

        // 总发电量 (kWh)=年发电量 (kWh)×运营年限 (年)
        BigDecimal zfdl = nfdl.multiply(BigDecimal.valueOf(Double
                .parseDouble(windPowerDto.getYynx()))).setScale(2, RoundingMode.HALF_UP);

        // 总收益 (元)=总发电量 (kWh)×上网电价 (元/kWh)×分成比例
        BigDecimal fcbl = (BigDecimal.valueOf(10).subtract(BigDecimal.valueOf(Double.parseDouble(windPowerDto.getFcbl()))))
                .divide(BigDecimal.valueOf(10));
        BigDecimal zsy = zfdl.multiply(BigDecimal.valueOf(Double.parseDouble(windPowerDto.getSwdj())))
                .multiply(fcbl).setScale(2, RoundingMode.HALF_UP);

        // 年收益 (元)=年发电量 (kWh)×上网电价 (元/kWh)×分成比例
        BigDecimal nsy = nfdl.multiply(BigDecimal.valueOf(Double
                        .parseDouble(windPowerDto.getSwdj()))).multiply(fcbl)
                .setScale(2, RoundingMode.HALF_UP);

        // 总减碳量 (吨CO₂)=总发电量 (kWh)×减碳系数 (吨CO₂/kWh)
        BigDecimal zjtl = zfdl.multiply(BigDecimal.valueOf(Double.parseDouble(windPowerDto.getJtxs())))
                .setScale(2, RoundingMode.HALF_UP);

        // 年运维成本 (元)=电站规模 (kW)×每KW运维成本 (元/kW/年)
        BigDecimal nywcb = dzgm.multiply(BigDecimal.valueOf(Double
                        .parseDouble(windPowerDto.getMkwywcb())))
                .setScale(2, RoundingMode.HALF_UP);

        // 回报周期 (年)=总投资 (元)/(年收益 (元)−年运维成本 (元))
        BigDecimal hbzq = ztz.divide(nsy.subtract(nywcb), 2, RoundingMode.HALF_UP);

        // 投资收益率=(年收益 (元)−年运维成本 (元)/总投资 (元))×100%
        BigDecimal tzsyl = (nsy.subtract(nywcb)).divide(ztz, 2, RoundingMode.HALF_UP)
                .multiply(BigDecimal.valueOf(100));

        WindPowerVo windPowerVo = new WindPowerVo();
        windPowerVo.setDzgm(dzgm.toString());
        windPowerVo.setZtz(ztz.toString());
        windPowerVo.setNfdl(nfdl.toString());
        windPowerVo.setZfdl(zfdl.toString());
        windPowerVo.setZsy(zsy.toString());
        windPowerVo.setNsy(nsy.toString());
        windPowerVo.setNywcb(nywcb.toString());
        windPowerVo.setHbzq(hbzq.toString());
        windPowerVo.setTzsyl(tzsyl.toString());
        windPowerVo.setZjtl(zjtl.toString());

        return windPowerVo;
    }

    @Override
    public LightStorageMicroNetworkVo lightStorageMicroNetwork(LightStorageMicroNetworkDto dto) {

        // 创建输出实体对象
        LightStorageMicroNetworkVo vo = new LightStorageMicroNetworkVo();

        // 计算光伏装机容量，基于屋顶面积和发电效率
//        BigDecimal gfzjrl = BigDecimal.valueOf(Double.parseDouble(dto.getWdmj()))
//                .multiply(BigDecimal.valueOf(Double.parseDouble(dto.getFdxl())))
//                .setScale(2, RoundingMode.HALF_UP);
        BigDecimal gfzjrl = BigDecimal.valueOf(Double.parseDouble(dto.getBzrl()));

        // 储能装机容量
        BigDecimal cnzjrl = gfzjrl.multiply(BigDecimal.valueOf(Double.parseDouble(
                dto.getGfpcbl()))).setScale(2, RoundingMode.HALF_UP);

        /**
         * 总投资包括光伏和储能的建设成本：
         * 总投资 (元)=光伏建设成本 (元)+储能建设成本 (元)
         * 其中：
         * 光伏建设成本 (元)=光伏装机容量 (kW)×每KW光伏建设成本 (元/kW)
         * 储能建设成本 (元)=储能装机容量 (kW)×储能单位造价 (元/kW)
         */
        BigDecimal gfjscb = gfzjrl.multiply(BigDecimal.valueOf(Double.parseDouble(dto.getMkwgfjscb())))
                .setScale(2, RoundingMode.HALF_UP);

        BigDecimal cnjscb = cnzjrl.multiply(BigDecimal.valueOf(Double.parseDouble(dto.getCndwzj())))
                .setScale(2, RoundingMode.HALF_UP);
        BigDecimal ztz = gfjscb.add(cnjscb).setScale(2, RoundingMode.HALF_UP);

        //单位面积安装容量
        BigDecimal dymjzjrl = gfzjrl.divide(BigDecimal.valueOf(Double.parseDouble(dto.getWdmj())), 2, RoundingMode.HALF_UP);

        //光伏年发电量 (kWh)=光伏装机容量 (kW)×满发小时数 (h)
        BigDecimal gfnfdl = gfzjrl.multiply(BigDecimal.valueOf(Double.parseDouble(dto.getNlyxss())))
                .setScale(2, RoundingMode.HALF_UP);
        //储能放电量,储能年放电量 (kWh)=储能装机容量 (kW)×放电时长 (h)×运营时间 (天)
        BigDecimal cndfdl = cnzjrl.multiply(BigDecimal.valueOf(Double.parseDouble(dto.getFdsc())))
                .multiply(BigDecimal.valueOf(Double.parseDouble(dto.getYysj())))
                .setScale(2, RoundingMode.HALF_UP);
        //年发电量
        BigDecimal nfdl = gfnfdl.add(cndfdl);

        //总发电量
        BigDecimal zfdl = nfdl.multiply(BigDecimal.valueOf(Double.parseDouble(dto.getYysj())))
                .setScale(2, RoundingMode.HALF_UP);

        // 计算总收益，假设所有产生的电力都以电网电价售出并扣除分成比例
        //总收益 (元)= 光伏总收益 (元)+储能总收益 (元)
        //光伏年收益 (元)=光伏年发电量 (kWh)×上网电价 (元/kWh)×分成比例
        BigDecimal fcbl = BigDecimal.valueOf(10).subtract(BigDecimal.valueOf(Double.parseDouble(dto.getFcbl())))
                .divide(BigDecimal.valueOf(10));
        BigDecimal gfnsy = gfnfdl.multiply(BigDecimal.valueOf(Double.parseDouble(dto.getSwdj())))
                .multiply(fcbl).setScale(2, RoundingMode.HALF_UP);
        //储能年收益 (元)=储能年放电量 (kWh)×峰谷电价差 (元/kWh)
        //峰谷差价
        BigDecimal fgcj = BigDecimal.valueOf(Double.parseDouble(dto.getFsdj()))
                .subtract(BigDecimal.valueOf(Double.parseDouble(dto.getGsdj())));
        BigDecimal cnnsy = cndfdl.multiply(fgcj).setScale(2, RoundingMode.HALF_UP);
        //年收益
        BigDecimal nsy = gfnsy.add(cnnsy);
        //总收益
//        BigDecimal zsy = nsy.multiply(BigDecimal.valueOf(Double.parseDouble(dto.getYysj())))
//                .setScale(2, RoundingMode.HALF_UP);

        // 计算总减碳量，总减碳量 (吨CO₂)=总发电量 (kWh)×减碳系数 (吨CO₂/kWh)
        BigDecimal zjtl = zfdl.multiply(BigDecimal.valueOf(Double.parseDouble(dto.getJtxs())))
                .setScale(2, RoundingMode.HALF_UP);

        // 计算年运维成本，年运维成本 (元)=光伏运维成本 (元)+储能运维成本 (元)
        //光伏运维成本 (元)=光伏装机容量 (kW)×每KW光伏运维成本 (元/kW/年)
        BigDecimal gfywcb = BigDecimal.valueOf(Double.parseDouble(dto.getMkwgfywcb())).divide(gfzjrl
                , 2, RoundingMode.HALF_UP);
        //储能运维成本 (元)=储能装机容量 (kW)×储电池运维成本 (元/kW/年)
        BigDecimal cnywcb = BigDecimal.valueOf(Double.parseDouble(dto.getCdcywcb())).divide(cnzjrl
                , 2, RoundingMode.HALF_UP);
        BigDecimal nywcb = gfywcb.add(cnywcb);

        // 计算回报周期，回报周期 (年)=总投资 (元)/(年收益 (元)−年运维成本 (元))
        BigDecimal hbzq = ztz.divide(nsy.subtract(nywcb), 2, RoundingMode.HALF_UP);

        // 计算投资收益率,投资收益率=(年收益 (元)−年运维成本 (元))/总投资 (元)×100%
        BigDecimal tzsyl = nsy.subtract(nywcb).divide(ztz, 2, RoundingMode.HALF_UP);
        // 储能系统功率 等于光伏装机容量乘以光伏配储比例
//        BigDecimal cnxtgl = gfzjrl.multiply(BigDecimal.valueOf(Double.parseDouble(dto.getGfpcbl())))
//                .setScale(2, RoundingMode.HALF_UP);
//        //每kw光伏建设成本 ，光伏建设成本/屋顶面积
//        BigDecimal mkwgfjscb = BigDecimal.valueOf(Double.parseDouble(dto.getMkwgfjscb()))
//                .divide(BigDecimal.valueOf(Double.parseDouble(dto.getWdmj())), 2, RoundingMode.HALF_UP);
//        //每kw光伏运维成本 ，光伏运维总成本/报装容量
//        BigDecimal mkwfywzcb = BigDecimal.valueOf(Double.parseDouble(dto.getGfywzcb()))
//                .divide(gfzjrl, 2, RoundingMode.HALF_UP);

        // 返回计算结果
        vo.setGfzjrl(gfzjrl.toString());
        vo.setCnzjrl(cnzjrl.toString());
        vo.setZtz(ztz.toString());
        vo.setGfjscb(gfjscb.toString());
        vo.setCnjscb(cnjscb.toString());
        vo.setDwmjazrl(dymjzjrl.toString());
        vo.setNfdl(nfdl.toString());
        vo.setGfnfdl(gfnfdl.toString());
        vo.setCnnfdl(cndfdl.toString());
        vo.setNfdl(nfdl.toString());
        vo.setZfdl(zfdl.toString());
//        vo.setZsy(zsy.toString());
        vo.setGfnsy(gfnsy.toString());
        vo.setCnnsy(cnnsy.toString());
//        vo.setFgdjc(fgcj.toString());
        vo.setHbzq(hbzq.toString());
        vo.setTzsyl(tzsyl.toString());
        vo.setZjtl(zjtl.toString());
        vo.setNywcb(nywcb.toString());
        vo.setNsy(nsy.toString());
        vo.setGfywcb(gfywcb.toString());
        vo.setCnywcb(cnywcb.toString());
//        vo.setMkwgfjscb(mkwgfjscb.toString());
//        vo.setMkwfywzcb(mkwfywzcb.toString());
        return vo;
    }


    @Override
    public LightStorageChargingVo lightStorageCharging(LightStorageChargingDto dto) {

        LightStorageChargingVo vo = new LightStorageChargingVo();

        // 计算光伏装机容量
        BigDecimal gfzjrl = BigDecimal.valueOf(Double.parseDouble(dto.getWdmj()))
                .multiply(BigDecimal.valueOf(Double.parseDouble(dto.getMkwgfsxmj())))
                .setScale(2, RoundingMode.HALF_UP);

        // 储能装机容量
        BigDecimal cnzjrl = BigDecimal.valueOf(Double.parseDouble(
                dto.getMkwcndcrl())).multiply(BigDecimal.valueOf(Double.parseDouble(
                dto.getCndczrl()))).setScale(2, RoundingMode.HALF_UP);

        BigDecimal cdzrl = BigDecimal.valueOf(Double.parseDouble(dto.getCdzsl()))
                .multiply(BigDecimal.valueOf(Double.parseDouble(dto.getDgccdzgl())))
                .setScale(2, RoundingMode.HALF_UP);

        //  总投资 (元) , 总投资=光伏建设成本+储能建设成本+充电桩建设成本+变压器建设成本+土建施工成本
        //光伏建设成本 电站规模 (kW)×每KW光伏建设成本 (元/kW)
        BigDecimal gfjscb = gfzjrl.multiply(BigDecimal.valueOf(Double.parseDouble(
                dto.getMkwgfjscb()))).setScale(2, RoundingMode.HALF_UP);
        // 储能建设成本
        BigDecimal cnjscb = cnzjrl.multiply(BigDecimal.valueOf(Double
                .parseDouble(dto.getCndwzj()))).setScale(2, RoundingMode.HALF_UP);
        // 充电桩建设成本
        BigDecimal cdzjscb = BigDecimal.valueOf(Double.parseDouble(dto.getCdzsl()))
                .multiply(BigDecimal.valueOf(Double.parseDouble(dto.getDgcdzdj())))
                .setScale(2, RoundingMode.HALF_UP);
        // 土建施工总成本 土建施工总成本 (元)=土建施工面积 (平方米)×土建施工单价 (元/平方米)
        BigDecimal tjsgzcb = BigDecimal.valueOf(Double.parseDouble(dto.getCdzjsmj()))
                .multiply(BigDecimal.valueOf(Double.parseDouble(dto.getTjgsdj())))
                .setScale(2, RoundingMode.HALF_UP);
        //配电设备总成本
        BigDecimal byqrl = BigDecimal.valueOf(Double.parseDouble(dto.getByqrl()));
        BigDecimal pdsbzcb = byqrl.multiply(BigDecimal.valueOf(Double.parseDouble(dto.getPdsbdj())))
                .setScale(2, RoundingMode.HALF_UP);
        //总投资=光伏建设成本+储能建设成本+充电桩建设成本+土建施工成本
        BigDecimal ztz = gfjscb.add(cnjscb).add(cdzjscb).add(tjsgzcb);

        //光伏年发电量 (kWh)
        // 计算年发电量 年发电量 (kWh)=电站规模 (kW)×满发小时数 (h)×(1−首年衰减)×发电效率
        BigDecimal nfdl = gfzjrl.multiply(BigDecimal.valueOf(Double.parseDouble(dto.getNlyxss())))
                .multiply((BigDecimal.valueOf(1)
                        .subtract(BigDecimal.valueOf(Double.parseDouble(dto.getSynx())))));
        //储能年发电量
        //年充放电次数
        BigDecimal ncfdcs = BigDecimal.valueOf(Double.parseDouble(dto.getDcsm()))
                .divide(BigDecimal.valueOf(Double.parseDouble(dto.getSynx())));

        BigDecimal cnnfdl = cnzjrl.multiply(BigDecimal.valueOf(Double.parseDouble(dto.getFdsc())))
                .multiply(ncfdcs).setScale(2, RoundingMode.HALF_UP);

        //年收益=光伏年收益+储能年收益+充电桩收益
        //光伏年收益 = 年发电量 (kWh)×上网电价 (元/kWh)
        BigDecimal gfnsy = nfdl.multiply(BigDecimal.valueOf(Double.parseDouble(dto.getSwdj())))
                .setScale(2, RoundingMode.HALF_UP);
        //储能年收益 = 储能年放电量 * (峰时电价 - 谷时电价)
        BigDecimal cnnsy = cnnfdl.multiply(BigDecimal.valueOf(Double.parseDouble(dto.getFsdj())
                        - Double.parseDouble(dto.getGsdj())))
                .setScale(2, RoundingMode.HALF_UP);
        //充电桩年收益=充电桩数量×充电桩使用率×充电单价×充电桩平均使用时长
        //充电单价=加权电价+服务费
        BigDecimal cddj = BigDecimal.valueOf(Double.parseDouble(dto.getJqdj()))
                .add(BigDecimal.valueOf(Double.parseDouble(dto.getFwf())));
        BigDecimal cdznsy = BigDecimal.valueOf(Double.parseDouble(dto.getCdzsl()))
                .multiply(BigDecimal.valueOf(Double.parseDouble(dto.getCdzpjsysc())))
                .multiply(BigDecimal.valueOf(Double.parseDouble(dto.getSyl())))
                .multiply(cddj).setScale(2, RoundingMode.HALF_UP);
        BigDecimal nsy = gfnsy.add(cnnsy).add(cdznsy);

        //回报周期 (年) 回报周期=总投资/年收益
        BigDecimal hbzq = ztz.divide(nsy, 2, RoundingMode.HALF_UP);

        //投资收益率 (IRR)  投资收益率（IRR）=年收益/总投资×100
        BigDecimal tzsyl = nsy.divide(ztz, 2, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100));

        //储能系统功率
        BigDecimal cnxtgl = ncfdcs.multiply(BigDecimal.valueOf(Double.parseDouble(dto.getCndczrl())))
                .setScale(2, RoundingMode.HALF_UP);
        vo.setGfzjrl(gfzjrl.toString());
        vo.setCnzjrl(cnzjrl.toString());
        vo.setCdzzjrl(cdzrl.toString());
        vo.setGfjscb(gfjscb.toString());
        vo.setCdzzcb(cdzjscb.toString());
        vo.setTjsgzcb(tjsgzcb.toString());
        vo.setPdsbzcb(pdsbzcb.toString());
        vo.setCnjscb(cnjscb.toString());
        vo.setZtz(ztz.toString());
        vo.setNfdl(nfdl.toString());
        vo.setCnnfdl(cnnfdl.toString());
        vo.setNsy(nsy.toString());
        vo.setGfnsy(gfnsy.toString());
        vo.setCnnsy(cnnsy.toString());
        vo.setCdznsy(cdznsy.toString());
        vo.setHbzq(hbzq.toString());
        vo.setTzsyl(tzsyl.toString());
        vo.setCnxtgl(cnxtgl.toString());
        vo.setNcfdcs(ncfdcs.toString());
        vo.setCddj(cddj.toString());
        return vo;
    }

    @Override
    public List<CalculationFormOptionsVo> getCalculationFormOptions(String calculationType) {
        LambdaQueryWrapper<CalculationFormOptionsEntity> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(CalculationFormOptionsEntity::getCalculationType, calculationType);
        List<CalculationFormOptionsEntity> list = calculationFormOptionsService.list(wrapper);
        List<CalculationFormOptionsVo> calculationFormOptionsVos = new ArrayList<>();
        if (list != null && list.size() > 0) {
            Map<String, List<CalculationFormOptionsEntity>> listMap = list.stream().collect(Collectors.groupingBy(CalculationFormOptionsEntity::getOptionCategory));
            for (Map.Entry<String, List<CalculationFormOptionsEntity>> entry : listMap.entrySet()) {
                CalculationFormOptionsVo calculationFormOptionsVo = new CalculationFormOptionsVo();
                calculationFormOptionsVo.setOptionCategory(entry.getKey());
                List<CalculationFormOptionsEntity> value = entry.getValue();
                if (value != null && value.size() > 0) {
                    List<CalculationFormOptionsVo.OptionValue> optionValues = new ArrayList<>();
                    for (CalculationFormOptionsEntity calculationFormOptionsEntity : value) {
                        CalculationFormOptionsVo.OptionValue optionValue = new CalculationFormOptionsVo.OptionValue();
                        optionValue.setOptionValue(calculationFormOptionsEntity.getOptionValue());
                        optionValue.setOptionName(calculationFormOptionsEntity.getOptionName());
                        optionValues.add(optionValue);
                    }
                    calculationFormOptionsVo.setValueList(optionValues);
                }
                calculationFormOptionsVos.add(calculationFormOptionsVo);
            }
        }
        return calculationFormOptionsVos;
    }

    @Override
    public FeedInTariffVo getFeedInTariff(String economize) {
        FeedInTariffVo feedInTariffVo = new FeedInTariffVo();
        List<FeedInTariffEntity> list = feedInTariffService.list();
        if (list != null && list.size() > 0) {
            for (FeedInTariffEntity feedInTariffEntity : list) {
                if (economize.contains(feedInTariffEntity.getEconomize())) {
                    feedInTariffVo.setFdsnlyxss(feedInTariffEntity.getFdsnlyxss());
                    feedInTariffVo.setSwdj(feedInTariffEntity.getSwdj());
                }
            }
        }
        ElectricityPriceDto dto = new ElectricityPriceDto();
        dto.setRegionName(economize);
        dto.setElectricityTypeOneName("BIPARTITE_SYSTEM");
        dto.setElectricityTypeTwoName("BUSINESS_NDUSTRY");
        dto.setTariffLevelId("14");
        if (economize.equals("广西壮族自治区") || economize.equals("河南省") ||
                economize.equals("宁夏回族自治区") || economize.equals("云南省")) {
            dto.setTariffLevelId("13");
        }
        if (economize.contains("陕西")) {
            dto.setTariffLevelId("6");
            dto.setElectricityTypeTwoName("LARGE_INDUSTRY");
        }
        if (economize.equals("青海省")) {
            dto.setTariffLevelId("6");
        }
        if (economize.contains("浙江省") || economize.equals("上海市") ) {
            dto.setElectricityTypeTwoName("GENERAL_INDUSTRY_COMMERCE");
        }
        JSONObject monthChooseData = photovoltaicService.getMonthChooseData(dto);
        if (monthChooseData.getInteger("resp_code").equals(0)) {
            JSONArray dataList = monthChooseData.getJSONArray("datas");
            if (dataList != null && dataList.size() > 0) {
                List<MonthChooseVo> monthChooseVos = JSON.parseArray(JSON.toJSONString(dataList), MonthChooseVo.class);
                MonthChooseVo monthChooseVo = monthChooseVos.get(monthChooseVos.size() - 1);
                dto.setYears(monthChooseVo.getParamName());
                JSONObject jsonObject = photovoltaicService.getDivideHourElectricityData(dto);
                if (jsonObject.getInteger("resp_code").equals(0)) {
                    JSONArray datas = jsonObject.getJSONArray("datas");
                    if (datas != null && datas.size() > 0) {
                        List<DivideHourVo> divideHourVos = JSON.parseArray(JSON.toJSONString(datas), DivideHourVo.class);
                        Map<String, List<DivideHourVo>> collect = divideHourVos.stream().collect(Collectors.groupingBy(DivideHourVo::getPeriodType));
                        Double highTime = Optional.ofNullable(collect.get("highTime"))
                                .orElse(Collections.emptyList())
                                .stream()
                                .mapToDouble(p -> Double.parseDouble(p.getElectrovalence()))
                                .average()
                                .orElse(0.0);
                        BigDecimal highTimeDB = new BigDecimal(highTime).setScale(3, RoundingMode.HALF_UP);
                        Double flatTime = Optional.ofNullable(collect.get("flatTime"))
                                .orElse(Collections.emptyList())
                                .stream()
                                .mapToDouble(p -> Double.parseDouble(p.getElectrovalence()))
                                .average()
                                .orElse(0.0);
                        BigDecimal flatTimeDB = new BigDecimal(flatTime).setScale(3, RoundingMode.HALF_UP);
                        Double lowTime = Optional.ofNullable(collect.get("lowTime"))
                                .orElse(Collections.emptyList())
                                .stream()
                                .mapToDouble(p -> Double.parseDouble(p.getElectrovalence()))
                                .average()
                                .orElse(0.0);
                        BigDecimal lowTimeDB = new BigDecimal(lowTime).setScale(3, RoundingMode.HALF_UP);
//                        DivideHourVo highTime = collect.get("highTime").get(0);
//                        DivideHourVo flatTime = collect.get("flatTime").get(0);
//                        DivideHourVo lowTime = collect.get("lowTime").get(0);
                        feedInTariffVo.setJqdj(flatTimeDB.toString());
                        feedInTariffVo.setFsdj(highTimeDB.toString());
                        feedInTariffVo.setGsdj(lowTimeDB.toString());
                    }
                }
            }
        }
        return feedInTariffVo;
    }

    @Override
    public List<RegionNameVo> getRegionName() {
        ElectricityPriceDto dto = new ElectricityPriceDto();
        JSONObject jsonObject = photovoltaicService.getRegionAndElectricityTypeIData(dto);
        if (jsonObject.getInteger("resp_code").equals(0)) {
            JSONArray dataList = jsonObject.getJSONArray("datas");
            if (dataList != null && dataList.size() > 0) {
                List<RegionVo> regionNameVos = JSON.parseArray(JSON.toJSONString(dataList), RegionVo.class);
                List<RegionNameVo> regionList = new ArrayList<>();
                for (RegionVo regionNameVo : regionNameVos) {
                    RegionNameVo region = new RegionNameVo();
                    region.setRegionName(regionNameVo.getRegionName());
                    regionList.add(region);
                }
                return regionList;
            }
        }
        return null;
    }

}
